﻿using System;
using System.Diagnostics;
using System.Resources;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using SpaceNeedle.x6473.WindowsPhone.Common;
using SpaceNeedle.x6473.WindowsPhone.ViewModels;
using SpaceNeedle.SDK.WindowsPhone;
using Microsoft.Phone.Notification;
using System.Text;
using System.Windows.Threading;

namespace SpaceNeedle.x6473.WindowsPhone
{
    public partial class App : Application
    {
        /// <summary>
        /// Provides easy access to the root frame of the Phone Application.
        /// </summary>
        /// <returns>The root frame of the Phone Application.</returns>
        public static PhoneApplicationFrame RootFrame { get; private set; }

        public static NetworkService NetworkService { get; set; }
        /// <summary>
        /// Constructor for the Application object.
        /// </summary>
        public App()
        {
            new AppServices();
            new AppViewModel();

            App.NetworkService = new Common.NetworkService();
            
            //ThemeManager.ToLightTheme();

            // Global handler for uncaught exceptions.
            UnhandledException += Application_UnhandledException;

            // Standard XAML initialization
            InitializeComponent();

            // Phone-specific initialization
            InitializePhoneApplication();

            // Language display initialization
            InitializeLanguage();


            // Show graphics profiling information while debugging.
            if (Debugger.IsAttached)
            {
                // Display the current frame rate counters.
                Application.Current.Host.Settings.EnableFrameRateCounter = true;

                // Show the areas of the app that are being redrawn in each frame.
                //Application.Current.Host.Settings.EnableRedrawRegions = true;

                // Enable non-production analysis visualization mode,
                // which shows areas of a page that are handed off to GPU with a colored overlay.
                //Application.Current.Host.Settings.EnableCacheVisualization = true;

                // Prevent the screen from turning off while under the debugger by disabling
                // the application's idle detection.
                // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
                // and consume battery power when the user is not using the phone.
                PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
            }

        }

        public static void CreatePushNotificationChannel()
        {
            try
            {
                string channelName = "X6473PushChannel";

                pushChannel = HttpNotificationChannel.Find(channelName);

                if (pushChannel == null)
                {
                    pushChannel = new HttpNotificationChannel(channelName);
                    pushChannel.ChannelUriUpdated += pushChannel_ChannelUriUpdated;
                    pushChannel.ErrorOccurred += pushChannel_ErrorOccurred;
                    pushChannel.ShellToastNotificationReceived += pushChannel_ShellToastNotificationReceived;

                    pushChannel.Open();

                    pushChannel.BindToShellToast();
                }
                else
                {
                    pushChannel.ChannelUriUpdated += pushChannel_ChannelUriUpdated;
                    pushChannel.ErrorOccurred += pushChannel_ErrorOccurred;
                    pushChannel.ShellToastNotificationReceived += pushChannel_ShellToastNotificationReceived;
                }

                if (pushChannel.ChannelUri != null)
                {
                    AppViewModel.Instance.Properties.PushNotificationChannelUri = pushChannel.ChannelUri;
                }
            }
            catch { }
        }

        private ShellToast toast = null;
        private static HttpNotificationChannel pushChannel = null;

        static async void pushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
        {
            if (e.ChannelUri != null)
            {
                AppViewModel.Instance.Properties.PushNotificationChannelUri = pushChannel.ChannelUri;

                await Api.SetPushNotificationChannelUri(AppViewModel.Instance.Properties.Me, AppViewModel.Instance.Properties.PushNotificationChannelUri);
            }
        }

        private static void pushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
        {
            return;

            //if(e.Collection.ContainsKey("wp:Param"))
            //{
            //    toast = new ShellToast();
            //    toast.Title = e.Collection["wp:Text1"];
            //    toast.Content = e.Collection["wp:Text2"];
            //    toast.NavigationUri = new Uri(e.Collection["wp:Param"], UriKind.RelativeOrAbsolute);

            //    toast.Show();
            //}

            return;
            StringBuilder message = new StringBuilder();
            string relativeUri = string.Empty;

            message.AppendFormat("Received Toast {0}:\n", DateTime.Now.ToShortTimeString());

            // Parse out the information that was part of the message.
            foreach (string key in e.Collection.Keys)
            {
                message.AppendFormat("{0}: {1}\n", key, e.Collection[key]);

                if (string.Compare(
                    key,
                    "wp:Param",
                    System.Globalization.CultureInfo.InvariantCulture,
                    System.Globalization.CompareOptions.IgnoreCase) == 0)
                {
                    relativeUri = e.Collection[key];
                }
            }

            App.Current.RootVisual.Dispatcher.BeginInvoke(() => MessageBox.Show(message.ToString()));
        }

        static void pushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
        {
            int a = 0;
        }

        

        // Code to execute when the application is launching (eg, from Start)
        // This code will not execute when the application is reactivated
        private async void Application_Launching(object sender, LaunchingEventArgs e)
        {
            await AppViewModel.Instance.RestoreAppState();
            await AppViewModel.Instance.IncrementExecutions();
        }

        // Code to execute when the application is activated (brought to foreground)
        // This code will not execute when the application is first launched
        private async void Application_Activated(object sender, ActivatedEventArgs e)
        {
            if (e.IsApplicationInstancePreserved)
            {
                return;
            }

            await AppViewModel.Instance.RestoreAppState();
            await AppViewModel.Instance.IncrementExecutions();
        }

        // Code to execute when the application is deactivated (sent to background)
        // This code will not execute when the application is closing
        private async void Application_Deactivated(object sender, DeactivatedEventArgs e)
        {
            await AppViewModel.Instance.SaveAppState();
        }

        // Code to execute when the application is closing (eg, user hit Back)
        // This code will not execute when the application is deactivated
        private async void Application_Closing(object sender, ClosingEventArgs e)
        {
            //await AppViewModel.Instance.SaveAppState();
        }

        // Code to execute if a navigation fails
        private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            if (Debugger.IsAttached)
            {
                // A navigation has failed; break into the debugger
                Debugger.Break();
            }

            Tracking.SendException(e.Exception, true);
        }

        // Code to execute on Unhandled Exceptions
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                Debugger.Break();
            }

            Tracking.SendException(e.ExceptionObject, true);

            e.Handled = true;
        }

        #region Phone application initialization

        // Avoid double-initialization
        private bool phoneApplicationInitialized = false;

        // Do not add any additional code to this method
        private void InitializePhoneApplication()
        {
            if (phoneApplicationInitialized)
                return;

            // Create the frame but don't set it as RootVisual yet; this allows the splash
            // screen to remain active until the application is ready to render.
            RootFrame = new PhoneApplicationFrame();
            RootFrame.Navigated += CompleteInitializePhoneApplication;

            // Handle navigation failures
            RootFrame.NavigationFailed += RootFrame_NavigationFailed;

            // Handle reset requests for clearing the backstack
            RootFrame.Navigated += CheckForResetNavigation;

            AppServices.Current.NavigationService = new SpaceNeedle.SDK.WindowsPhone.Services.NavigationService(RootFrame);
            // Ensure we don't initialize again
            phoneApplicationInitialized = true;
        }

        // Do not add any additional code to this method
        private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
        {
            // Set the root visual to allow the application to render
            if (RootVisual != RootFrame)
                RootVisual = RootFrame;

            // Remove this handler since it is no longer needed
            RootFrame.Navigated -= CompleteInitializePhoneApplication;
        }

        private void CheckForResetNavigation(object sender, NavigationEventArgs e)
        {
            // If the app has received a 'reset' navigation, then we need to check
            // on the next navigation to see if the page stack should be reset
            if (e.NavigationMode == NavigationMode.Reset)
                RootFrame.Navigated += ClearBackStackAfterReset;
        }

        private void ClearBackStackAfterReset(object sender, NavigationEventArgs e)
        {
            // Unregister the event so it doesn't get called again
            RootFrame.Navigated -= ClearBackStackAfterReset;

            // Only clear the stack for 'new' (forward) and 'refresh' navigations
            if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh)
                return;

            // For UI consistency, clear the entire page stack
            while (RootFrame.RemoveBackEntry() != null)
            {
                ; // do nothing
            }
        }

        #endregion

        // Initialize the app's font and flow direction as defined in its localized resource strings.
        //
        // To ensure that the font of your application is aligned with its supported languages and that the
        // FlowDirection for each of those languages follows its traditional direction, ResourceLanguage
        // and ResourceFlowDirection should be initialized in each resx file to match these values with that
        // file's culture. For example:
        //
        // AppResources.es-ES.resx
        //    ResourceLanguage's value should be "es-ES"
        //    ResourceFlowDirection's value should be "LeftToRight"
        //
        // AppResources.ar-SA.resx
        //     ResourceLanguage's value should be "ar-SA"
        //     ResourceFlowDirection's value should be "RightToLeft"
        //
        // For more info on localizing Windows Phone apps see http://go.microsoft.com/fwlink/?LinkId=262072.
        //
        private void InitializeLanguage()
        {
            try
            {
                // Set the font to match the display language defined by the
                // ResourceLanguage resource string for each supported language.
                //
                // Fall back to the font of the neutral language if the Display
                // language of the phone is not supported.
                //
                // If a compiler error is hit then ResourceLanguage is missing from
                // the resource file.
                //RootFrame.Language = XmlLanguage.GetLanguage(AppResources.ResourceLanguage);

                // Set the FlowDirection of all elements under the root frame based
                // on the ResourceFlowDirection resource string for each
                // supported language.
                //
                // If a compiler error is hit then ResourceFlowDirection is missing from
                // the resource file.
                //FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection);
                //RootFrame.FlowDirection = flow;
            }
            catch
            {
                // If an exception is caught here it is most likely due to either
                // ResourceLangauge not being correctly set to a supported language
                // code or ResourceFlowDirection is set to a value other than LeftToRight
                // or RightToLeft.

                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }

                throw;
            }
        }
    }
}